﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Opennav.MapGenerator.Geometry
{
    public class Coordinate
    {
        public static int MAX_RESOLUTION = 24;

        public Coordinate(int longitude, int latitude)
        {
            this.Longitude = longitude;
            this.Latitude = latitude;
        }

        public int Longitude { get; private set; }
        public int Latitude { get; private set; }
        public double dLongitude
        {
            get
            {
                return IntToDoubleCoordinate(Longitude);
            }
        }

        public double dLatitude
        {
            get
            {
                return IntToDoubleCoordinate(Latitude);
            }
        }

        public override bool Equals(object obj)
        {
            if (obj == this)
                return true;
            if (!(obj is Coordinate))
                return false;
            Coordinate other = obj as Coordinate;
            if (other.Longitude == Longitude && other.Latitude == Latitude)
                return true;
            else
                return false;
        }

        public static double EARTH_RADIUS = 6371000;

        public double Distance(Coordinate other)
        {
            if (other.Longitude == this.Longitude && other.Latitude == this.Latitude) return 0.0f;
            double aLat = Rad(IntToDoubleCoordinate(Latitude));
            double bLat = Rad(IntToDoubleCoordinate(other.Latitude));
            double aLon = Rad(IntToDoubleCoordinate(Longitude));
            double bLon = Rad(IntToDoubleCoordinate(other.Longitude));
            return (double)(EARTH_RADIUS * Math.Acos(Math.Sin(aLat) * Math.Sin(bLat) + Math.Cos(aLat) * Math.Cos(bLat) * Math.Cos(bLon - aLon)));
        }

        public static double Rad(double degree)
        {
            return degree * 3.1415926 / 180.0;
        }

        public static Coordinate FromCoordinates(double longitude, double latitude)
        {
            return new Coordinate(DoubleToIntCoordinate(longitude), DoubleToIntCoordinate(latitude));
        }

        public static int DoubleToIntCoordinate(double value)
        {
            return (int)(value * (16777216.0 / 360.0));
        }

        public static double IntToDoubleCoordinate(int value)
        {
            return (double)(value * (360.0 / 16777216.0));
        }
    }
}
